package crm.salesOrderProcessing.session;

import commonInfrastructure.accountManagement.entity.EmployeeEntity;
import commonInfrastructure.accountManagement.entity.SalesmanEntity;
import commonInfrastructure.accountManagement.session.EmployeeSessionBean;
import commonInfrastructure.system.session.AuditTrailSessionBean;
import commonInfrastructure.system.session.SystemSessionBean;
import crm.clientManagement.entity.CompanyEntity;
import crm.clientManagement.session.CompanySessionBean;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.ejb.Stateless;
import javax.ejb.LocalBean;
import javax.faces.model.SelectItem;
import javax.persistence.Query;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import crm.salesOrderProcessing.entity.LineItemEntity;
import crm.salesOrderProcessing.entity.ProductEntity;
import crm.salesOrderProcessing.entity.SalesQuotationEntity;
import crm.salesOrderProcessing.util.exception.QuotationNotFoundException;
import crm.salesOrderProcessing.util.exception.SalesException;
import java.util.Properties;
import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.ejb.EJB;
import javax.faces.context.FacesContext;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.servlet.http.HttpServletRequest;

@Stateless
@LocalBean
public class SalesQuotationSessionBean {

    @PersistenceContext
    private EntityManager em;
    
    @EJB
    CompanySessionBean companySession = new CompanySessionBean();
    @EJB
    EmployeeSessionBean employee;
    @EJB
    SystemSessionBean systemSession = new SystemSessionBean();
    @EJB
    AuditTrailSessionBean auditSession = new AuditTrailSessionBean();

    public SalesQuotationEntity addNewSalesQuotation(CompanyEntity selectedCompany, List<LineItemEntity> lineItemList, Date validUntil, double totalPrice, double userDiscount, int LeadTime) throws SalesException,ParseException {
        SalesQuotationEntity salesQuotation = new SalesQuotationEntity();
        //System.out.print(selectedCompany);
        salesQuotation.setCompany(selectedCompany);
        em.flush();
        salesQuotation.setQuotationLineItems(lineItemList);
        salesQuotation.setTotalPrice(totalPrice);
        salesQuotation.setUserDiscount(userDiscount);
        salesQuotation.setValidUntil(validUntil);
        salesQuotation.setRaiseDate(getTodayDate());
        salesQuotation.setLeadTime(LeadTime);
        
        EmployeeEntity user = systemSession.getCurrentUser();
        salesQuotation.setProcessedBy(user.getName());
        
        em.persist(salesQuotation);
        em.flush();
        
        //Audit Trail
        auditSession.addAuditTrail(systemSession.getToday(), salesQuotation.getId(), user.getUserName(), "crm.salesOrderProcessing", "Sales Quotation", "Create", "");
        
        return salesQuotation;
    }
    
    private Date getTodayDate()throws ParseException{
       Calendar calendar = Calendar.getInstance();
       SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
 
       String dateString= dateFormat.format(calendar.getTime());
       return dateFormat.parse(dateString);   
      
    }

    public List<SalesQuotationEntity> getAllSalesQuotations() {
        Query query = em.createQuery("SELECT q1 FROM SalesQuotationEntity q1");
        return query.getResultList();
    }

    public void deleteSalesQuotationLineItems(Long quotationId) {
        SalesQuotationEntity salesQuotation = em.find(SalesQuotationEntity.class, quotationId);
        List<LineItemEntity> lineItems = salesQuotation.getQuotationLineItems();
        for (Object o : lineItems) {
            LineItemEntity li = (LineItemEntity) o;
            em.remove(li);
        }
        salesQuotation.setQuotationLineItems(null);
        em.flush();
    }
    
      public void deleteSalesQuotation(Long quotationId) throws ParseException{
        SalesQuotationEntity salesQuotation = em.find(SalesQuotationEntity.class,quotationId);
        List <LineItemEntity> lineItems = salesQuotation.getQuotationLineItems();
        for (Object o: lineItems){
            LineItemEntity li = (LineItemEntity)o;
            em.remove(li);
        }
        em.remove(salesQuotation);
        
        //Audit Trail
        EmployeeEntity user = systemSession.getCurrentUser();
        auditSession.addAuditTrail(systemSession.getToday(), salesQuotation.getId(), user.getUserName(), "crm.salesOrderProcessing", "Sales Quotation", "Delete", "");
    }

    public void deleteSalesOrder(Long id) {
        SalesQuotationEntity salesQuotationEntity = em.find(SalesQuotationEntity.class, id);
        em.remove(salesQuotationEntity);
    }

    public List<SalesQuotationEntity> getAllSalesQuotation() {
        HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        Long loginId = (Long) request.getSession().getAttribute("userId");
        SalesmanEntity user = employee.getSalesmanById(loginId);
        
        if (user.getSalesManLevel().equals("4")){
            Query query = em.createQuery("SELECT sl FROM SalesQuotationEntity sl");
            return query.getResultList();
        }
        else{
            List<CompanyEntity> companyList = companySession.getCompaniesBySalesman(user.getId());
            List<SalesQuotationEntity> quotationList = new ArrayList<SalesQuotationEntity>();
            for (int i=0;i<companyList.size();i++){
                for (int j=0;j<companyList.get(i).getSalesQuotations().size();j++){
                    quotationList.add(companyList.get(i).getSalesQuotations().get(j));
                }
            }
            return quotationList;
        }

    }
    
    public List<SalesQuotationEntity> getQuotationByUser(SalesmanEntity user){
        List<CompanyEntity> companyList = companySession.getCompaniesBySalesman(user.getId());
        List<SalesQuotationEntity> quotationList = new ArrayList<SalesQuotationEntity>();
        for (int i=0;i<companyList.size();i++){
            for (int j=0;j<companyList.get(i).getSalesQuotations().size();j++){
                quotationList.add(companyList.get(i).getSalesQuotations().get(j));
            }
        }
        return quotationList;
    }

    public ProductEntity getProduct(String productName) {
        Query query = em.createQuery("SELECT p FROM ProductEntity p WHERE p.productName = :inProductName");
        query.setParameter("inProductName", productName);
        ProductEntity product = null;
        try {
            product = (ProductEntity) query.getSingleResult();
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return product;
    }
    
    public void saveChanges(SalesQuotationEntity salesQuotation) throws ParseException{
        em.merge(salesQuotation);
        //Audit Trail
        EmployeeEntity user = systemSession.getCurrentUser();
        auditSession.addAuditTrail(systemSession.getToday(), salesQuotation.getId(), user.getUserName(), "crm.salesOrderProcessing", "Sales Quotation", "Edit", "");
    }
//    public ProductEntity getProductByCode(String productCode) {
//        
//        Query query = em.createQuery("SELECT p FROM ProductEntity p WHERE p.productName = :inProductCode"); //should change ProductEntity properbility from product Nmae to product Code?
//        //in database, store each product by its code ->A,B,C,D
//        query.setParameter("inProductCode", productCode);
//        ProductEntity product = null;
//        try {
//            product = (ProductEntity) query.getSingleResult();
//        } catch (NoResultException ex) {
//            ex.printStackTrace();
//        }
//        return product;
//    }
    
    public List<SelectItem> getProductList(SalesQuotationEntity salesQuotation) {
    if(salesQuotation == null)
    {
         return new ArrayList<SelectItem>();
    }
    else
    {
    ArrayList result = new ArrayList();
    List<LineItemEntity> lineItems = salesQuotation.getQuotationLineItems();
    
    List<SelectItem> selectItems = new ArrayList<SelectItem>();
    
    
    for (LineItemEntity lineItem : lineItems) {
    
    selectItems.add(new SelectItem(lineItem.getProduct().getId(), lineItem.getProduct().getProductName()));
    }
    return selectItems;
    }
    }
    

    public CompanyEntity getCompanyByName(String companyName) {

        Query query = em.createQuery("SELECT c FROM CompanyEntity c WHERE c.name = :inCompanyName");
        query.setParameter("inCompanyName", companyName);
        CompanyEntity company = null;
        try {
            company = (CompanyEntity) query.getSingleResult();
        } catch (NoResultException ex) {
            ex.printStackTrace();
        }
        return company;
    }

    public SalesQuotationEntity getQuotationById(Long quotationId) throws QuotationNotFoundException {
//        Query query = em.createQuery("SELECT q FROM SalesQuotationEntity q WHERE q.id = :inQuotationId");
//        query.setParameter("inQuotationId",quotationId );
//        SalesQuotationEntity quotation = new SalesQuotationEntity();
//        try{
//        quotation = (SalesQuotationEntity)query.getSingleResult();
//        }
//        catch(NoResultException ex){
//            ex.printStackTrace();
//        }
        SalesQuotationEntity quotation = em.find(SalesQuotationEntity.class, quotationId);
        if (quotation == null)
        {
            throw new QuotationNotFoundException();
        }
        return quotation;
    }
    
    public void sendSalesQuotation(String toEmailAddress, SalesQuotationEntity quotation, String path){
        Properties props = new Properties();
		props.put("mail.smtp.host", "smtp.gmail.com");
		props.put("mail.smtp.socketFactory.port", "465");
		props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.auth", "true");
		props.put("mail.smtp.port", "465");
                
		Session session = Session.getInstance(props,
			new javax.mail.Authenticator() {@Override
protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication("melionfood.m04","weloveyoutwk");
				}
			});
 
		try {
			Message message = new MimeMessage(session);
                        

                        
			message.setFrom(new InternetAddress("melionfood.m04@gmail.com"));
			message.setRecipients(Message.RecipientType.TO,
					InternetAddress.parse(toEmailAddress));
                        
                        List<LineItemEntity> lineItemList = quotation.getQuotationLineItems();
                        String content = "Dear " + quotation.getCompany().getContactPersonTitle()+" "+quotation.getCompany().getContactPersonName() + ":"
					 + "\n\nHere is your sales quotaiton for your company "+quotation.getCompany().getName()
                                         + "\n________________________________________________________________\n"
                                         + "\nID: "+quotation.getId()+"\nTotal Price: "+quotation.getTotalPrice()+"\nUser Discount: "+quotation.getUserDiscount()
                                         + "\nEstimated Lead Time: "+quotation.getLeadTime()+"\nValid Until: "+quotation.getValidUntil().toString()
                                         + "\n\nAttached is the quotation details."
                                         + "\n________________________________________________________________\n"
                                         + "\n\nPlease feel free to contact me if you want to raise a purchase order."
                                         + "\n\n\nThanks,\n" + quotation.getCompany().getSalesman().getName()+"\nMerlion Food limieted Sales Department";
                        
			message.setSubject("Sales Inquiry Result");
			
                        Multipart multipart = new MimeMultipart();
                        MimeBodyPart mimeBodyPart1 = new MimeBodyPart();
                        MimeBodyPart mimeBodyPart2 = new MimeBodyPart();

                        mimeBodyPart1.setText(content);

                        String filePath = path+"/SalesQuotation_"+quotation.getId()+".pdf";
                        DataSource dataSource = new FileDataSource(filePath);
                        mimeBodyPart2.setDataHandler(new DataHandler(dataSource));
                        mimeBodyPart2.setFileName("Sales Quotation");

                        multipart.addBodyPart(mimeBodyPart1);
                        multipart.addBodyPart(mimeBodyPart2);

                        message.setContent(multipart);

			Transport.send(message);
 
			System.out.println("Done");
 
		} catch (MessagingException e) {
			throw new RuntimeException(e);
		}
    }
}
